home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
smaltalk
/
stv.lha
/
STV
/
st_v
/
util
/
STVUTIL5.ZIP
/
PUBLIC.WIN
< prev
next >
Wrap
Text File
|
1993-02-07
|
11KB
|
305 lines
"This Smalltalk/V Windows filein allows you to create a new
type of browser, called a Public Method Browser. It is identical
in all respects to a standard Class Hierarchy Browser, except
that it shows only public methods.
A public method is generally distinguished by the inclusion
of the word 'Private' as the first word in the first comment in
the method. This code assumes that placement, but it is
easily modified. Note that doing so will significantly slow
initialization.
The Public Method Browser uses a global variable, PublicMethods,
which contains a dictionary of all public methods in your
system. It MUST be initialized before you can use the
Public Method Browser.
To install, file in this file by selecting it and choosing FileIn
from the Smalltalk menu.
You will be prompted for creation of the PublicMethods global.
Respond 'Yes' to this prompt.
To initialize the PublicMethods dictionary, evaluate the expression
PublicBrowser initialize
This process takes a few minutes, since it needs to scan all of
the source code currently in your system.
To open a Public Method Browser, evaluate the expression
PublicBrowser new openOn: (Array with: Object)
or add the Public Method Browser to the File menu by modifying the
ApplicationWindow>>fileMenu method. If you choose to do this,
evaluate the expression
Notifier reinitialize
so the Transcript menu will include this change.
New Global Variable: PublicMethods
New Class: PublicBrowser
New Instance Methods: PublicBrowser>>label
PublicBrowser>>selectors
New Class Methods: PublicBrowser>>initialize
PublicBrowser>>initializeClassDictionary
PublicBrowser>>initializeInstanceDictionary
Modified Methods: Behavior>>compile:notifying
Behavior>>removeSelector
ClassHierarchyBrowser>>addSubClass
ClassHierarchyBrowser>>removeSubClass"
ClassHierarchyBrowser subclass: #PublicBrowser
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: '' !
PublicMethods := Dictionary new!
!PublicBrowser class methods !
initialize
"Initialize the public class and instance dictionaries."
Transcript nextPutAll: 'Initializing Public Dictionaries...';cr.
self
initializeClassDictionary;
initializeInstanceDictionary.
Transcript nextPutAll: 'Public dictionaries initialized.'!
initializeClassDictionary
"Initialize the class method dictionary."
| classes |
classes := Object withAllSubclasses reject: [ : c | c printString first = $ ].
classes do: [ : className |
PublicMethods
at: className class put: Set new.
Transcript nextPutAll: 'Examining methods in ',className printString,'.';cr.
className class selectors do: [ :selectorName |
(((ReadStream on: (className sourceCodeAt: selectorName)) upTo: $";
nextWord ) = 'Private')
ifFalse: [
(PublicMethods at: className class) add: selectorName] ] ]!
initializeInstanceDictionary
"Initialize the instance method dictionary."
| classes |
classes := Object withAllSubclasses reject: [ : c | c printString first = $ ].
classes do: [ : className |
PublicMethods
at: className put: Set new.
Transcript nextPutAll: 'Examining methods in ',className printString,'.';cr.
className selectors do: [ :selectorName |
(((ReadStream on: (className sourceCodeAt: selectorName)) upTo: $";
nextWord ) = 'Private')
ifFalse: [
(PublicMethods at: className) add: selectorName] ] ]! !
!PublicBrowser methods !
label
"Private - Answer the window label."
^'Public Method Browser'!
selectors: selectorPane
"Private - Set the sorted list of public method
selectors for the selected class and type
(class or instance)."
| methods |
selectedClass isNil
ifTrue: [^selectorPane contents: Array new].
instanceSelectedLast
ifTrue: [
selectedInstVar isNil
ifTrue: [^selectorPane contents: (PublicMethods at: selectedClass ) asSortedCollection]
ifFalse: [
methods := assigned
ifTrue: [
used
ifTrue: [selectedClass allMethodsReferencingInstVar: selectedInstVar]
ifFalse: [selectedClass allMethodsAssigningInstVar: selectedInstVar]]
ifFalse: [
used
ifTrue: [selectedClass allMethodsUsingInstVar: selectedInstVar]
ifFalse: [^selectorPane contents: selectedClass selectors asSortedCollection]].
methods := methods select: [:m | (PublicMethods at: selectedClass)
includes: m selector].
^selectorPane contents: (methods collect: [:m | m selector]) asSortedCollection]]
ifFalse: [
^selectorPane contents: (PublicMethods at: selectedClass class) asSortedCollection] ! !
!Behavior methods !
removeSelector: aSymbol
"Remove the method named aSymbol from
the methods defined in the receiver.
Note: This version has been modified so that the selectors
for public methods are removed from the PublicMethods global
dictionary."
self methodDictionary
removeKey: aSymbol
ifAbsent: [].
"The following code is for the Public Method Browser."
(PublicMethods at: self ifAbsent: [^nil])
remove: aSymbol
ifAbsent: []!
compile: codeString notifying: requestor
"Compile the Smalltalk method contained in codeString.
The class to use for resolving variables is the receiver.
If there are no errors, add the method to the recevier
messageDictionary and answer the Association with the
message selector as the key and the compiled method
as the value. If there is an error the requestor is sent
a message by the compiler identitfying the error and
this method answers nil.
Note: This method has been modified so that compiled
methods are added to the Public Method Dictionary
if appropriate."
| answer |
answer := Compiler
compile: codeString
in: self
notifying: requestor
ifFail: [^nil].
"Check for method defined from a browser if new method
for class redefines method in superclass. If so, ask
for confirmation before installing method."
((requestor isWindow)
and: [(self includesSelector: answer key) not])
ifTrue: [ "from browser and new method"
(self canUnderstand: answer key)
ifTrue: [ "a superclass defines it"
(MessageBox
titled: 'Caution'
withText: 'You are redefining a superclass method.'
style: MbOkcancel)
= Idok ifFalse: [^nil]]].
self addSelector: answer key withMethod: answer value.
"The following code is for the Public Method Browser."
(((ReadStream on: codeString) upTo: $";
nextWord ) = 'Private')
ifFalse: [
(PublicMethods at: self ifAbsent: [^answer]) add: answer key].
^answer! !
!ClassHierarchyBrowser methods !
addSubClass
"Private - Add a subclass to the selected
class. If a class is selected, prompt the
user for a new class name and add it as a
subclass to the selected class."
| newSubclassDialog newName subclassType |
selectedClass isNil ifTrue: [selectedClass := Object].
newSubclassDialog := NewSubclassDialog open: selectedClass.
newName := newSubclassDialog subclassName.
(newName isNil or: [newName isEmpty])
ifTrue: [^nil].
(newName at: 1) isUpperCase
ifFalse: [
newName at: 1
put: (newName at: 1) asUpperCase].
newName := newName asSymbol.
(Smalltalk includesKey: newName)
ifTrue: [^self error: newName, ' already exists'].
subclassType := newSubclassDialog isFixed
ifTrue: [#pointer]
ifFalse: [newSubclassDialog isPointer
ifTrue: [#indexed]
ifFalse: [#byte]].
(subclassType == #pointer and: [selectedClass isVariable])
ifTrue: [
(MessageBox confirm: 'Indexed pointer subclass assumed')
ifFalse: [^self]].
subclassType == #pointer
ifTrue: [
((selectedClass subclass: newName
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: '')
isKindOf: Class)
ifFalse: [^self]].
subclassType == #indexed
ifTrue: [
((selectedClass variableSubclass: newName
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: '')
isKindOf: Class)
ifFalse: [^self]].
subclassType == #byte
ifTrue: [
((selectedClass variableByteSubclass: newName
classVariableNames: ''
poolDictionaries: '')
isKindOf: Class)
ifFalse: [^self]].
subclassType isNil ifTrue: [^self].
selectedClass := Smalltalk at: newName asSymbol.
CursorManager execute change.
selectedMethod := nil.
methodSelectedLast := false.
self update: originalClasses.
self
changed: #hierarchy:
with: #restoreSelected:
with: ((String new:
(Smalltalk at: newName asSymbol)
allSuperclasses size * 2)
atAllPut: $ ), newName.
"The following is for the Public Browser."
PublicMethods
at: selectedClass put: Set new;
at: selectedClass class put: Set new.
self
changed: #selectors: ;
changed: #instanceVars: ;
changed: #text: !
removeSubClass
"Private - Delete the selected class."
| newName subclassType answer |
selectedClass isNil
ifTrue: [^nil].
(MessageBox confirm: 'Delete Class "', selectedClass name, '"?')
ifFalse: [^nil].
CursorManager execute change.
selectedClass removeFromSystem.
selectedMethod := nil.
methodSelectedLast := false.
self update: originalClasses.
self changed: #hierarchy:
with: #restore.
"The following is for the Public Browser."
PublicMethods
removeKey: selectedClass;
removeKey: selectedClass class.
selectedClass := nil.
self
changed: #selectors: ;
changed: #instanceVars: ;
changed: #text: ! !